{layout name="../../admin/view/layout/main" /}
{:breadcrumb(['UI 示例:example/layout/index', '上传插件:example/upload/index', 'cropper图片裁剪'])}
<style>
    /* 裁剪样式 */
    .image-wrapper {
        height: 364px;
        width: 100%;
        box-shadow: inset 0 0 3px rgba(0, 0, 0, .075);
        background-color: #fcfdfe;
        overflow: hidden;
    }
    .image-preview {
        float: left;
        margin-bottom: 0.5rem;
        margin-right: 0.5rem;
        border: 1px solid #f1f2f3;
        border-radius: 2px;
        background-color: #fff;
        overflow: hidden;
    }
    .image-preview img {
        vertical-align: top;
    }
    .preview-lg {
      height: 4.5rem;
      width: 8rem;
    }
    .preview-md {
      height: 2.25rem;
      width: 4rem;
    }
    .preview-sm {
      height: 1.125rem;
      width: 2rem;
    }
    .preview-xs {
      height: 0.5625rem;
      margin-right: 0;
      width: 1rem;
    }
    @media (max-width: 991px) {
        #image-modal .image-btns {
            margin-bottom: 15px;
        }
    }
    [data-theme='dark'] .image-wrapper,
    [data-theme|='translucent'] .image-wrapper,
    [data-theme='dark'] .image-preview,
    [data-theme|='translucent'] .image-preview {
        background-color: rgba(var(--bs-white-rgb), .2);
    }
    [data-theme='dark'] .image-preview,
    [data-theme|='translucent'] .image-preview {
        border-color: rgba(var(--bs-white-rgb), .2);
    }
    </style>

<div class="row">

    <div class="col-lg-12">
      <div class="card">
        <header class="card-header">
          <div class="card-title">图片裁剪插件cropper</div>
        </header>
        <div class="card-body">
        
          <p>这里上传采用base64的方式。</p>
        <div class="mb-3">
          <label for="picurl_one" class="form-label">没有图片地址的新上传</label>
          <div class="input-group">
            <input type="text" class="form-control image-src" name="picurl_one" value="" id="picurl_one" />
            <button class="btn btn-default trigger-btn" type="button">上传图片</button>
          </div>
        </div>
        
        <div class="mb-3">
          <label for="picurl_two" class="form-label">已有图片地址的修改操作</label>
          <div class="input-group">
            <input type="text" class="form-control image-src" name="picurl_two" id="picurl_two" value="./data/upload/images/lyear_6371ef6827655.jpg" />
            <button class="btn btn-default trigger-btn" type="button">上传图片</button>
          </div>
        </div>
        
        </div>
      </div>
  </div>

</div>

<!--图片裁剪START-->
<div class="modal fade" id="image-modal">
    <div class="modal-dialog modal-lg">
      <div class="modal-content">
  
        <div class="modal-header">
          <h6 class="modal-title" id="image-modal-label">上传图片</h6>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="image-body">
            <div class="image-upload mb-3">
              <button class="btn btn-primary" type="button" onclick="$('input[id=imageInput]').click();">请选择图片</button>
              <span class="image-name"></span>
              <input type="file" class="image-input d-none" id="imageInput" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff">
            </div>
            <div class="row">
              <div class="col-lg-9 mb-3">
                <div class="image-wrapper"></div>
              </div>
              <div class="col-lg-3">
                <div class="image-previews clearfix">
                  <div class="image-preview preview-lg"></div>
                  <div class="image-preview preview-md"></div>
                  <div class="image-preview preview-sm"></div>
                  <div class="image-preview preview-xs"></div>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-lg-4 image-btns">
                <button class="btn btn-primary mdi mdi-rotate-left" data-method="rotate" data-option="-45" type="button" title="向左旋转-45度"></button>
                <button class="btn btn-primary mdi mdi-rotate-right" data-method="rotate" data-option="45" type="button" title="向右旋转45度"></button>
                <button type="button" class="btn btn-primary mdi mdi-magnify-plus-outline" data-method="zoom" data-option="0.1" title="放大图片"></button>
                <button type="button" class="btn btn-primary mdi mdi-magnify-minus-outline" data-method="zoom" data-option="-0.1" title="缩小图片"></button>
                <button type="button" class="btn btn-primary mdi mdi-cached" data-method="reset" title="重置图片"></button>
              </div>
              <div class="col-lg-5 image-btns toggles-btns">
                <div class="btn-group">
                  <input type="radio" name="aspectRatio" class="btn-check" id="aspectRatio1" value="1.7777777777777777" checked>
                  <label class="btn btn-outline-primary" for="aspectRatio1">16:9</label>
                  <input type="radio" name="aspectRatio" class="btn-check" id="aspectRatio2" value="1.3333333333333333">
                  <label class="btn btn-outline-primary" for="aspectRatio2">4:3</label>
                  <input type="radio" name="aspectRatio" class="btn-check" id="aspectRatio3" value="1">
                  <label class="btn btn-outline-primary" for="aspectRatio3">1:1</label>
                  <input type="radio" name="aspectRatio" class="btn-check" id="aspectRatio4" value="0.6666666666666666">
                  <label class="btn btn-outline-primary" for="aspectRatio4">2:3</label>
                  <input type="radio" name="aspectRatio" class="btn-check" id="aspectRatio5" value="NaN">
                  <label class="btn btn-outline-primary" for="aspectRatio5">自适应</label>
                </div>
              </div>
              <div class="col-lg-3 d-grid">
                <button class="btn btn-primary btn-block upload-btn mdi mdi-content-save" type="submit">保存修改</button>
              </div>
            </div>
          </div>
        </div>
        
      </div>
    </div>
  </div>
  <!--图片裁剪END-->

  <script type="text/javascript">
    function cropImage()
    {
        this.$uploadUrl    = "{:url('example/upload/upload_base64')}";                     // 上传地址
        this.$triggerBtn   = $('.trigger-btn');                            // 上传按钮
        this.$imageModal   = $('#image-modal');                            // 弹出框
        this.$imageName    = this.$imageModal.find('.image-name')          // 图片名称
        this.$imageInput   = this.$imageModal.find('.image-input');        // file上传文件
        this.$imageUpload  = this.$imageModal.find('.image-upload');       // file所在元素
        this.$imageBtns    = this.$imageModal.find('.image-btns');         // 图片调整按钮(旋转、放大等)
        this.$imageWrapper = this.$imageModal.find('.image-wrapper');      // 图片处理区域
        this.$imagePreview = this.$imageModal.find('.image-preview');      // 图片裁剪预览区域
        this.$uploadBtn    = this.$imageModal.find('.upload-btn');         // 上传按钮
        this.$togglesBtns  = this.$imageModal.find('.toggles-btns');       // 比例切换按钮
        this.URL           = window.URL || window.webkitURL;
        this.$options      = {
            aspectRatio: 16 / 9,
            preview: '.image-preview'
        };                                                                 // 配置
        this.init();
    }
    cropImage.prototype = {
        constructor: cropImage,
        init: function() {
            this.initModal();
            this.addListener();
        },
        initModal: function() {
            this.$imageModal.modal({
                show: false
            });
            
            if(!URL) {
                this.$imageInput.prop('disabled', true);
            }
        },
        addListener: function() {
            // 绑定事件
            this.$triggerBtn.on('click', $.proxy(this.click, this));
            this.$imageInput.on('change', $.proxy(this.change, this));
            this.$togglesBtns.on('change', $.proxy(this.choose, this));
            this.$uploadBtn.on('click', $.proxy(this.ajaxUpload, this));
            this.$imageBtns.on('click', $.proxy(this.rotate, this));
        },
        click: function(e) {
            // 点击上传按钮
            this.$imageText = $(e.target).prev('.image-src');
            this.$imageModal.modal('show');
            this.initPreview();
        },
        initPreview: function() {
            this.active = false;
            this.$imageInput.val('');
            this.$imageName.text('');
            this.$imageWrapper.empty();
            // 如果已有图片地址，初始化图片预览区域
            this.$imagePreview.empty();
            var url = this.$imageText.val();
            (url.length > 0) && this.$imagePreview.html('<img src="' + url + '">');
        },
        change: function() {
            // 选择图片
            var files, file;
            files = this.$imageInput.prop('files');
            
            if (files && files.length > 0) {
                file = files[0];
                if (this.isImageFile(file)) {
                    this.$imageType = file.type;
                    this.$imageName.text(file.name);
                    if (this.imageUrl) {
                        this.URL.revokeObjectURL(this.imageUrl);
                    }
                    this.imageUrl = this.URL.createObjectURL(file);
                    this.startCropper();
                }
            }
        },
        startCropper: function() {
            // 选择图片后初始化
            if (this.active) {
                this.$image.cropper('replace', this.imageUrl, true);
            } else {
                this.$image = $('<img src="' + this.imageUrl + '">');
                this.$imageWrapper.empty().html(this.$image);
                this.$image.cropper('destroy').cropper(this.$options);
                
                this.active = true;
            }
        },
        isImageFile: function(file) {
            // 判断是否图片格式
            if (file.type) {
                return /^image\/\w+$/.test(file.type);
            } else {
                return /\.(jpg|jpeg|png|gif|bmp|tiff)$/.test(file);
            }
        },
        choose: function(e) {
            var $this = $(e.target);
            var name  = $this.attr('name');
            
            if (!this.active) {
                return;
            }
            
            this.$options[name] = $this.val();
            this.$image.cropper('destroy').cropper(this.$options);
        },
        rotate: function(e) {
            // 调整图片操作
            var data;
            if (this.active) {
                data = $(e.target).data();
                if (data.method) {
                    this.$image.cropper(data.method, data.option);
                }
            }
        },
        stopCropper: function() {
            // 裁剪上传完成后重置
            if (this.active) {
                this.$image.cropper('destroy');
                this.$image.remove();
                this.$imageModal.modal('hide');
                this.$imageInput.val('');
                this.$imageName.text('');
                this.$togglesBtns.find('#aspectRatio1').attr('checked', true);
                this.active = false;
            }
        },
        ajaxUpload: function() {
            var cas        = this.$image.cropper('getCroppedCanvas'),
                base64Data = cas.toDataURL(this.$imageType),
                _this      = this,
                $loading;
            
            // ajax上传
            $.ajax(this.$uploadUrl, {
                type: 'post',
                data: {"picdata" : base64Data},
                dataType: 'json',
                beforeSend: function() {
                    _this.$uploadBtn.prop('disabled', true);
                    $loading = $('.upload-btn').lyearloading({
                        opacity: 0.2,
                        spinnerSize: 'nm'
                    });
                },
                success: function(data) {
                    if ($.isPlainObject(data) && data.state === 200) {
                        _this.$imageText.val(data.picurl);
                        _this.stopCropper();
                    } else {
                        showNotify(data.message, 'danger', 3000);
                    }
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log(textStatus);
                },
                complete: function() {
                    _this.$uploadBtn.prop('disabled', false);
                    $loading.destroy();
                }
            });
        }
    };
    $(document).ready(function(){
        new cropImage();
    });
    </script>